package com.higgins.client.knowledge.trainer;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Logger;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.higgins.client.GreetingService;
import com.higgins.client.GreetingServiceAsync;
import com.higgins.client.dataModel.CoveringLetterDTO;
import com.higgins.client.dataModel.StrategyDTO;
import com.higgins.client.generic.components.GenericTable;
import com.higgins.client.knowledge.KnowledgeItemDTO;
import com.higgins.client.knowledge.KnowledgeService;
import com.higgins.client.knowledge.KnowledgeServiceAsync;

public class KnowledgeTrainerTable extends GenericTable	{
	private static final Logger log = Logger.getLogger(KnowledgeTrainerTable.class.getName());
	private final KnowledgeServiceAsync knowledgeService = GWT
			.create(KnowledgeService.class);
	private List<KnowledgeItemDTO> parentKnowledgeItemDTOs = null;
	private List<KnowledgeItemDTO> knowledgeItemDTOs = null;
	private KnowledgeItemDTO selectedKnowledgeItemParentDTO = null;
	private KnowledgeTrainerItemSelectedListener listener = null;
	private KnowledgeTrainerOracle oracle = new KnowledgeTrainerOracle();
	private Long parentId = null;
	private int lastRow = 0;
	
	public KnowledgeTrainerTable(KnowledgeTrainerColumns columns)	{
		super(columns);
	}
	
//	private List<List<Object>> convertDTOtoRowArray(List<KnowledgeItemDTO> knowledgeItemDTOs)	{
//		List<List<Object>> rows = new ArrayList<List<Object>>();
//		for (KnowledgeItemDTO knowledgeItemDTO:knowledgeItemDTOs)	{
//			List<Object> row = new ArrayList<Object>();
//			row.add(knowledgeItemDTO.getId());
//			row.add(knowledgeItemDTO.getItem());
//			row.add(knowledgeItemDTO.getRelationship());
//			row.add(knowledgeItemDTO.getTopLevel());
//			rows.add(row);
//		}
//		return rows;
//	}
	
	public void hint()	{
		List<KnowledgeItemDTO> remainingQuestions = oracle.getRemainingQuestions();
		try	{
			for (KnowledgeItemDTO remainingQuestion:remainingQuestions)	{
				updateRow(remainingQuestion);
			}
		} catch (Exception e)	{			
		}
	}
	private void updateRow(KnowledgeItemDTO question)	{
		setText(++lastRow, 3, question.getItem());
	}
	
	public void updateItemCell(int row)	{
		String answer = getText(row, 1);
		oracle.setAnswer(answer);
		if (oracle.identifyCorrectAnswer())	{
			setText(row, 2, "" + oracle.retrieveScore() + "%");
			setText(row, 3, oracle.retrieveCorrectAnswer());
			insertAttempt(oracle.retrieveAnswerId(), oracle.retrieveScore());
			oracle.nextQuestion();
		}
		lastRow = row;
		
//		KnowledgeItemDTO dto = knowledgeItemDTOs!=null?(knowledgeItemDTOs.size()>=row?knowledgeItemDTOs.get(row-1):null):null;
//		setText(row, 2, "" + calculateScore(answer, dto).toString() + "%");
//		setText(row, 3, dto!=null?dto.getItem():"Blank");
	}
	
//	private Integer calculateScore(String answer, KnowledgeItemDTO dto)	{
//		if (answer.toLowerCase().charAt(0)==(dto.getItem().toLowerCase().charAt(0)))	{
//			return 100;
//		} else {
//			return 0;
//		}
//	}
	
	private void insertAttempt(Long id, Integer score)	{
		knowledgeService.insertKnowledgeAttempt(id, score, new AsyncCallback<Boolean>() {

			@Override
			public void onFailure(Throwable caught) {
			}

			@Override
			public void onSuccess(Boolean result) {
			}
		});
	}
	
	protected void retrieveDTOs()	{
		try {
			knowledgeService.retrieveRandomKnowledgeItemRelationships(parentId, new AsyncCallback<List<KnowledgeItemDTO>>()	{
					@Override
					public void onFailure(Throwable caught) {
						log.info("KnowledgeItemDTO: " + caught.toString());
					}

					@Override
					public void onSuccess(List<KnowledgeItemDTO> result) {
						parentKnowledgeItemDTOs = result;
						nextQuestion();
					}
				});
		} catch (IllegalArgumentException e) {
			log.info("KnowledgeItemDTO: " + e.toString());
		} /*catch (SecurityAccessDeniedException e) {
			log.info("SecurityAccessDeniedException: " + e.toString());
		} */
	}	
	
	private List<List<Object>> createBlankRows(int size)	{
		List<List<Object>> rows = new ArrayList<List<Object>>();
		for (int count=0;count< size;count++)	{
			List<Object> row = new ArrayList<Object>();
			row.add(new Long(0l));
			row.add("");
			row.add("");
			row.add("");
			rows.add(row);
		}		
		return rows;
	}

/*	private void updateRow(KnowledgeItemDTO knowledgeItemDTO)	{
		try {
			knowledgeService.updateKnowledgeItem(knowledgeItemDTO, new AsyncCallback<Long>()	{
					@Override
					public void onFailure(Throwable caught) {
						log.info("KnowledgeItemDTO: " + caught.toString());
					}

					@Override
					public void onSuccess(Long result) {
						setRowIdAfterUpdate(result.toString());
					}
				});
		} catch (IllegalArgumentException e) {
			log.info("KnowledgeItemDTO: " + e.toString());
		} /*catch (SecurityAccessDeniedException e) {
			log.info("SecurityAccessDeniedException: " + e.toString());
		} 		
	}		*/
	public void nextQuestion()	{
		clearOutTable();
		initialise();
		lastRow = 0;
		initialiseTable(genericColumns);
		if (parentKnowledgeItemDTOs!=null && parentKnowledgeItemDTOs.size() > 0)	{
			int min = 0; 
			int max = parentKnowledgeItemDTOs.size() - 1;
			int randomId = min + (int)(Math.random() * ((max - min) + 1));
			selectedKnowledgeItemParentDTO = parentKnowledgeItemDTOs.get(randomId);
			knowledgeService.retrieveKnowledgeItems(null, selectedKnowledgeItemParentDTO.getId(), new AsyncCallback<List<KnowledgeItemDTO>>() {

				@Override
				public void onFailure(Throwable caught) {
					// TODO Auto-generated method stub
					
				}

				@Override
				public void onSuccess(List<KnowledgeItemDTO> results) {
					if (results.size()>0)	{
						KnowledgeItemDTO dto = results.get(0);
						knowledgeItemDTOs = results;
						loadData(createBlankRows(knowledgeItemDTOs.size()));						
						updateListener();
						oracle.setKnowledgeItems(knowledgeItemDTOs);
					}
				}
				
			});
		}
	}
	private void updateListener()	{
		if (listener!=null)	{
			listener.setKnowledgeTrainerItem(selectedKnowledgeItemParentDTO.getItem());
		}
	}
	public void addKnowledgeTrainerItemSelectedListener(KnowledgeTrainerItemSelectedListener listener)	{
		this.listener = listener;
	}
	protected void makeGenericCellEditable(final int row, final int column)	{
		Widget widget = getWidget(row, column);
		if (widget!=null && widget.getClass().equals(TextBox.class))	{
			return;
		}
		final TextBox textBox = new TextBox();
		textBox.setText(getText(row, column));
		textBox.setFocus(true);
		textBox.setCursorPos(0);
		setWidget(row, column, textBox);
		textBox.addKeyDownHandler(new KeyDownHandler() {

			@Override
			public void onKeyDown(KeyDownEvent event) {
				// TODO Auto-generated method stub
				int code = event.getNativeKeyCode();
				if (KeyCodes.KEY_ENTER == code || KeyCodes.KEY_TAB == code)	{
					setWidget(row, column, new Label(textBox.getText()));
					setRowUpdateTag(row);
					updateItemCell(row);
					if (getRowCount() > (row+1))	{		// PROBLEM HERE NULL POINTER!!!
						makeTableEditable((row+1), column);
					}
				}
				if (KeyCodes.KEY_ESCAPE == code)	{
					setWidget(row, column, new Label(textBox.getText()));
				}
			}
		});
		textBox.setFocus(true);
	}
	public void setParentId(Long id)	{
		parentId = id;
		retrieveDTOs();
	}
}